#include "StdAfx.h"

TerrainManager* Singleton<TerrainManager>::m_instance = NULL;

void TerrainManager::resetToAdt(ui32 indexX, ui32 indexZ, const std::string& continent) {
	mCurContinent = continent;
	memset(mAdtMask, 0, 9 * 4);

	for(i32 i = -1; i < 2; ++i) {
		for(i32 j = -1; j < 2; ++j) {
			mAdtMask[1 + i][1 + j] = (indexZ + i) * 1000 + indexX + j;
		}
	}
}

bool TerrainManager::pulse() {
	auto pos = sCamera.GetCamPosition();
	ui32 indexX = (ui32)floor(pos.x / TILESIZE);
	ui32 indexZ = (ui32)floor(pos.z / TILESIZE);
	ui32 mask = indexZ * 1000 + indexX;
	if(mAdtMask[1][1] == mask)
		return false;

	i32 oldX = (i32)(mAdtMask[1][1] % 1000);
	i32 oldZ = (i32)(mAdtMask[1][1] / 1000);
	i32 diffX = (i32)indexX - oldX;
	i32 diffZ = (i32)indexZ - oldZ;
	if(diffX == 1) {
		for(ui32 i = 0; i < 3; ++i) {
			ui32 del = mAdtMask[i][0];
			sD3D.RemoveAdt(del % 1000, del / 1000);
			mAdtMask[i][0] = mAdtMask[i][1];
			mAdtMask[i][1] = mAdtMask[i][2];
			mAdtMask[i][2] = mAdtMask[i][1] + 1;
			ui32 loadX = mAdtMask[i][2] % 1000;
			ui32 loadZ = mAdtMask[i][2] / 1000;

			std::stringstream strm;
			strm << "World\\Maps\\" << mCurContinent << "\\" << mCurContinent << "_" << loadX << "_" << loadZ << ".adt";
			std::string file = strm.str();
			Thread::executeFunction([file, loadX, loadZ]() {
				ADTModel* mod = new ADTModel(file);
				mod->m_indexX = loadX;
				mod->m_indexZ = loadZ;
				if(mod->Init())
					sD3D.AddAdt(mod, loadX, loadZ);
			});
		}
	} else if(diffX == -1) {
		for(ui32 i = 0; i < 3; ++i) {
			ui32 del = mAdtMask[i][2];
			sD3D.RemoveAdt(del % 1000, del / 1000);
			mAdtMask[i][2] = mAdtMask[i][1];
			mAdtMask[i][1] = mAdtMask[i][0];
			mAdtMask[i][0] = mAdtMask[i][1] - 1;
			ui32 loadX = mAdtMask[i][0] % 1000;
			ui32 loadZ = mAdtMask[i][0] / 1000;

			std::stringstream strm;
			strm << "World\\Maps\\" << mCurContinent << "\\" << mCurContinent << "_" << loadX << "_" << loadZ << ".adt";
			std::string file = strm.str();
			Thread::executeFunction([file, loadX, loadZ]() {
				ADTModel* mod = new ADTModel(file);
				mod->m_indexX = loadX;
				mod->m_indexZ = loadZ;
				if(mod->Init())
					sD3D.AddAdt(mod, loadX, loadZ);
			});
		}
	} else if(diffZ == 1) {
		for(ui32 i = 0; i < 3; ++i) {
			ui32 del = mAdtMask[0][i];
			sD3D.RemoveAdt(del % 1000, del / 1000);
			mAdtMask[0][i] = mAdtMask[1][i];
			mAdtMask[1][i] = mAdtMask[2][i];
			mAdtMask[2][i] = mAdtMask[1][i] + 1000;
			ui32 loadX = mAdtMask[2][i] % 1000;
			ui32 loadZ = mAdtMask[2][i] / 1000;

			std::stringstream strm;
			strm << "World\\Maps\\" << mCurContinent << "\\" << mCurContinent << "_" << loadX << "_" << loadZ << ".adt";
			std::string file = strm.str();
			Thread::executeFunction([file, loadX, loadZ]() {
				ADTModel* mod = new ADTModel(file);
				mod->m_indexX = loadX;
				mod->m_indexZ = loadZ;
				if(mod->Init())
					sD3D.AddAdt(mod, loadX, loadZ);
			});
		}
	} else if(diffZ == -1) {
		for(ui32 i = 0; i < 3; ++i) {
			ui32 del = mAdtMask[2][i];
			sD3D.RemoveAdt(del % 1000, del / 1000);
			mAdtMask[2][i] = mAdtMask[1][i];
			mAdtMask[1][i] = mAdtMask[0][i];
			mAdtMask[0][i] = mAdtMask[1][i] - 1000;
			ui32 loadX = mAdtMask[0][i] % 1000;
			ui32 loadZ = mAdtMask[0][i] / 1000;

			std::stringstream strm;
			strm << "World\\Maps\\" << mCurContinent << "\\" << mCurContinent << "_" << loadX << "_" << loadZ << ".adt";
			std::string file = strm.str();
			Thread::executeFunction([file, loadX, loadZ]() {
				ADTModel* mod = new ADTModel(file);
				mod->m_indexX = loadX;
				mod->m_indexZ = loadZ;
				if(mod->Init())
					sD3D.AddAdt(mod, loadX, loadZ);
			});
		}
	}
	return true;
}